﻿Namespace RemoteableObject

  ''' <summary>
  ''' Durch den Cache kann gewährleistet werden, dass alle Aufrufe auf das selbe Instanz zugreifen.
  ''' </summary>
  ''' <remarks></remarks>
  <System.Runtime.InteropServices.ComVisible(False)>
  Public Class Cache

    ''' <summary>
    ''' Die aktuelle Instanz des Cache.
    ''' </summary>
    ''' <remarks></remarks>
    Private Shared myInstance As Cache

    ''' <summary>
    ''' Das aktuelle IObserver-Objekt.
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared Observer As IObserver

    Sub New()
      MyBase.New()
    End Sub

    ''' <summary>
    ''' Hängt ein IObserver-Objekt an den Cache.
    ''' </summary>
    ''' <param name="observer"></param>
    ''' <remarks></remarks>
    Public Shared Sub Attach(ByRef observer As IObserver)
      Cache.Observer = observer
    End Sub

    ''' <summary>
    ''' Holt die aktuelle Instanz oder erstellt eine Neue.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetInstance() As Cache
      If Object.ReferenceEquals(myInstance, Nothing) Then
        myInstance = New Cache()
      End If
      Return myInstance
    End Function

    Public ReadOnly Property Result As Boolean
      Get
        Return Observer.Result
      End Get
    End Property

    Public ReadOnly Property Authenticate(ByVal User As String, ByVal Pass As String) As String
      Get
        Return Observer.Authenticate(User, Pass)
      End Get
    End Property

    Public ReadOnly Property DeleteValue(ByVal Token As String, ByVal Name As String) As Boolean
      Get
        Select Case Observer.DelValue(Token, Name)
          Case Auxiliary.EResult.FAILED
            Return False
          Case Auxiliary.EResult.SUCCESS
            Return True
          Case Auxiliary.EResult.NOAUTH
            Throw New Auxiliary.AuthenticationException("Not authenticated")
          Case Else
            Return False
        End Select
      End Get
    End Property

    Public ReadOnly Property ListDBs(Optional ByVal Identifier As String = "") As List(Of String)
      Get
        Return Observer.ListDBs(Identifier)
      End Get
    End Property

    Public ReadOnly Property ListValues(Optional ByVal Name As String = "") As Dictionary(Of String, String)
      Get
        Return Observer.ListValues(Name)
      End Get
    End Property

    Public ReadOnly Property ListPrivateValues(ByVal Identifier As Guid, Optional ByVal Name As String = "") As Dictionary(Of String, String)
      Get
        Return Observer.ListPrivateValues(Identifier, Name)
      End Get
    End Property

    Public Property Value(ByVal Token As String, ByVal Name As String) As String
      Get
        Return Observer.GetValue(Name)
      End Get
      Set(value As String)
        If Observer.SetValue(Token, Name, value) = Auxiliary.EResult.NOAUTH Then
          Throw New Auxiliary.AuthenticationException("Not authenticated")
        End If
      End Set
    End Property

    Public ReadOnly Property PrivateDeleteValue(ByVal Token As String, ByVal Name As String, ByVal Identifier As Guid) As Boolean
      Get
        Select Case Observer.DelPrivateValue(Token, Identifier, Name)
          Case Auxiliary.EResult.FAILED
            Return False
          Case Auxiliary.EResult.SUCCESS
            Return True
          Case Auxiliary.EResult.NOAUTH
            Throw New Auxiliary.AuthenticationException("Not authenticated")
          Case Else
            Return False
        End Select
      End Get
    End Property

    Public Property PrivateValue(ByVal Token As String, ByVal Name As String, ByVal Identifier As Guid) As String
      Get
        Return Observer.GetPrivateValue(Identifier, Name)
      End Get
      Set(value As String)
        If Observer.SetPrivateValue(Token, Identifier, Name, value) = Auxiliary.EResult.NOAUTH Then
          Throw New Auxiliary.AuthenticationException("Not authenticated")
        End If
      End Set
    End Property

    Public ReadOnly Property GetDB(ByVal Name As String, Optional ByVal CreateIfNotExist As Boolean = True) As String
      Get
        Return Observer.GetDB(Name, CreateIfNotExist)
      End Get
    End Property

    Public ReadOnly Property DeletDB(ByVal Token As String, ByVal Name As String) As Boolean
      Get
        Select Case Observer.DeleteDB(Token, Name)
          Case Auxiliary.EResult.FAILED
            Return False
          Case Auxiliary.EResult.SUCCESS
            Return True
          Case Auxiliary.EResult.NOAUTH
            Throw New Auxiliary.AuthenticationException("Not authenticated")
          Case Else
            Return False
        End Select
      End Get
    End Property

    Public ReadOnly Property Revoke(ByVal Token As String) As Boolean
      Get
        Return Observer.Revoke(Token)
      End Get
    End Property

  End Class
End Namespace